package com.yizhiliulianta.auth.domain.service.impl;


import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.google.gson.Gson;
import com.yizhiliulianta.auth.common.util.LoginUtil;
import com.yizhiliulianta.auth.domain.bo.AuthUserBO;
import com.yizhiliulianta.auth.domain.constants.AuthConstant;
import com.yizhiliulianta.auth.domain.converter.AuthUserBOConverter;
import com.yizhiliulianta.auth.domain.redis.RedisUtil;
import com.yizhiliulianta.auth.domain.service.AuthUserDomainService;
import com.yizhiliulianta.auth.infra.entity.AuthPermission;
import com.yizhiliulianta.auth.infra.entity.AuthUser;
import com.yizhiliulianta.auth.infra.entity.AuthUserPermission;
import com.yizhiliulianta.auth.infra.service.AuthPermissionService;
import com.yizhiliulianta.auth.infra.service.AuthUserPermissionService;
import com.yizhiliulianta.auth.infra.service.AuthUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;

@Service
@Slf4j
public class AuthUserDomainServiceImpl implements AuthUserDomainService {

    @Resource
    private AuthUserService authUserService;

    @Resource
    private AuthPermissionService authPermissionService;
    @Resource
    private AuthUserPermissionService authUserPermissionService;

    @Resource
    private RedisUtil redisUtil;

    private final String salt = "yizhiliulianta";
    private final String userPermissionPrefix = "user.permission";

    private static final String LOGIN_PREFIX = "loginCode";

    @Override
    public Boolean register(AuthUserBO authUserBO) {
        AuthUser existAuthUser = new AuthUser();
        existAuthUser.setUserName(authUserBO.getUserName());
        //校验用户是否存在
        List<AuthUser> existUser = authUserService.queryByCondition(existAuthUser);
        if (existUser.size() > 0){
            return true;
        }
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToAuth(authUserBO);
        if (StringUtils.isNotBlank(authUser.getPassword())){
            authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(),salt));
        }
        //插入用户
        AuthUser user = authUserService.insert(authUser);
        AuthPermission authPermission = new AuthPermission();
        //获取对应权限信息
        authPermission.setPermissionKey(AuthConstant.PERMISSION_KEY);
        AuthPermission permissionResult = authPermissionService.queryByCondition(authPermission);
        //用户与权限做关联
        Long userId = user.getId();
        Long permissionResultId = permissionResult.getId();
        AuthUserPermission authUserPermission = new AuthUserPermission();
        authUserPermission.setUserId(userId);
        authUserPermission.setPermissionId(permissionResultId);
        authUserPermissionService.insert(authUserPermission);
        //放入redis
        String buildKey = redisUtil.buildKey(userPermissionPrefix, authUser.getUserName());
        List<AuthPermission> authPermissionList = new LinkedList<>();
        authPermissionList.add(permissionResult);
        redisUtil.set(buildKey,new Gson().toJson(authPermissionList));

        return true;
    }

    @Override
    public SaTokenInfo doLogin(String validCode) {
        String loginKey = redisUtil.buildKey(LOGIN_PREFIX, validCode);
        String openId = redisUtil.get(loginKey);
        if (StringUtils.isBlank(openId)){
            return null;
        }
        AuthUserBO authUserBO = new AuthUserBO();
        authUserBO.setUserName(openId);
        this.register(authUserBO);
        StpUtil.login(openId);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return tokenInfo;
    }


    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToAuth(authUserBO);
        if (StringUtils.isBlank(authUserBO.getUserName())){
            String loginId = LoginUtil.getLoginId();
            authUser.setUserName(loginId);
        }
        List<AuthUser> authUsers = authUserService.queryByCondition(authUser);
        AuthUser user = authUsers.get(0);
        return AuthUserBOConverter.INSTANCE.convertToAuthBo(user);
    }

    @Override
    public AuthUserBO update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToAuth(authUserBO);
        if (StringUtils.isBlank(authUserBO.getUserName())){
            String loginId = LoginUtil.getLoginId();
            authUser.setUserName(loginId);
        }
        AuthUser updateUser = authUserService.update(authUser);
        return AuthUserBOConverter.INSTANCE.convertToAuthBo(updateUser);
    }
}
